package com.mamingchao.basics.designpattern.singleton;

/**
 * 5 是为了解决4的问题，这是比0 和1 还完美的解决方案
 *
 * Created by mamingchao on 2020/10/9.
 */
public class DoubleCheck5 {
    //如果用 JIT 优化的前提，java intime compiler
    //volatile 可以防止指令重排序，如果不加 可能 instance 没生成就先返回
    //当然，没有实用JIT优化的时候，不加也可以
    //因为 new 对象分三步，第一步申请内存，第二步给成员变量初始值，第三部 把 栈里面的instance 指向 这个新申请的内存区域
    //在 第三步执行的时候，可能第二步还没执行 内部成员变量还没有初始化赋值，就给返回回去了
    //第一个线程执行的时候，是上述的情况；第二个线程来的时候，做 instance == null 的判断，肯定是false，第二个线程就会拿这个instance
    //去用，很可能会用里面的 成员变量，这个时候 值还没进行初始化赋值，用到来错误的值
    private static volatile DoubleCheck5 instance;

    private DoubleCheck5(){}

    public static DoubleCheck5 getInstance(){
        if (instance == null) {
            synchronized(DoubleCheck5.class) {
                if (instance == null) {
                    instance = new DoubleCheck5();
                }
            }
        }
        return instance;
    }


    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
//                System.out.println(LazyMan.getInstance());
                System.out.println(DoubleCheck5.getInstance().hashCode());
            }).start();
        }
    }
}
